feat(cli): fbuild port scan with VID:PID friendly-name resolution (#741)#742
Conversation
Adds `fbuild port scan` — enumerates every visible serial port and
renders a two-row block per port:
COM25 303A:1001 USB Serial Device (COM25) ser=80:F1:B2:...
└─ Espressif Systems / ESP32-S3 USB-CDC
Row 2 resolves the VID:PID via the tiered fbuild_core::usb resolver
(tier 1 embedded vendor archive, tier 2 best-effort online overlay
fetched from FastLED/fbuild's online-data branch into a 7-day TTL
cache under fbuild_paths::get_cache_root().join("usb/")).
Beyond the resolver, the product column falls through this preference
chain so common embedded VID:PIDs the canonical FastLED/boards vidpid
table doesn't yet carry still render a friendly name:
1. Resolver product if non-synthetic (overlay hit)
2. Small inline supplement (ESP32 series, NXP LPC-Link2 / MCU-Link)
3. OS descriptor when chip-specific (e.g. macOS / Linux CP2102 strings)
4. Synthetic `Device 0xPPPP` placeholder
The blocking HTTP fetch runs on a dedicated OS thread so reqwest's
internal tokio runtime sees a clean async-free context — calling it
directly from inside the CLI dispatcher's #[tokio::main] outer runtime
would panic.
Closes #741
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughA new Changesfbuild port scan subcommand
Sequence Diagram(s)sequenceDiagram
actor User
participant fbuild_cli as fbuild CLI dispatcher
participant run_scan as run_scan()
participant CacheFS as Cache FS
participant USB_VID_JSON_URL
participant fbuild_core_usb as fbuild_core::usb
participant serialport
User->>fbuild_cli: fbuild port scan [--offline]
fbuild_cli->>run_scan: run_port(PortAction::Scan { offline })
alt not --offline
run_scan->>CacheFS: check overlay cache age (7-day TTL)
alt cache stale or missing
run_scan->>USB_VID_JSON_URL: GET overlay JSON (dedicated OS thread, 15s timeout)
USB_VID_JSON_URL-->>run_scan: JSON bytes
run_scan->>CacheFS: write .tmp → rename to cache file
end
run_scan->>fbuild_core_usb: install_overlay(bytes)
end
run_scan->>serialport: available_ports()
serialport-->>run_scan: Vec<SerialPortInfo>
loop per port
run_scan->>fbuild_core_usb: resolve(vid, pid)
fbuild_core_usb-->>run_scan: UsbInfo { vendor, product }
end
run_scan-->>User: rendered two-row-per-port output + summary
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Adds
fbuild port scan— enumerates every visible serial port and renders a two-row block per port with vendor + friendly product names resolved from VID:PID.Row 2 resolves the VID:PID via the tiered
fbuild_core::usbresolver:online-databranch into a 7-day TTL cache underfbuild_paths::get_cache_root().join("usb/")Device 0xPPPPplaceholderA small inline supplement (
FRIENDLY_PRODUCTS) covers common embedded VID:PIDs (ESP32-S3/C3/S2 USB-CDC, NXP LPC-Link2 / MCU-Link) that FastLED/boards' canonicalvidpidtable doesn't yet carry — those entries should be removed here as they land upstream.Implementation notes
--offlineflag skips the network fetch; tier-1 still provides vendor names.tmpsibling + rename — Ctrl+C mid-fetch won't poison the cachereqwest::blockingruns on a dedicated OS thread so its internal tokio runtime doesn't panic from nesting inside the CLI dispatcher's#[tokio::main]outer runtimerender_scan()function tested in isolation (11 unit tests pinning layout, summary pluralization, descriptor preference, supplement hits, non-USB ports)Test plan
cargo test -p fbuild-cli --bin fbuild cli::port_scan— 11/11 passfbuild port scanon a system with 4 ESP32-S3 + 1 NXP device — friendly names render correctlycargo clippy -p fbuild-cli --all-targets -- -D warnings— cleancargo fmt— appliedCloses #741
🤖 Generated with Claude Code
Summary by CodeRabbit
fbuild port scancommand to enumerate serial ports with USB vendor/product resolution--offlineflag available to skip online overlay updates